
package com.feib.soeasy.pagination;

import java.util.List;
import java.util.Map;

import com.feib.soeasy.util.CodeTableUtil;


/**
 * @title (#)PaginatedList.java<br>
 * @description describing an externally sorted and paginated list.<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/10/31 create by Jimmy Liu<br>
 */
public class PaginatedList<E> 
{
    public static final int SORT_DIRECTION_DESC = 1;
    
    public static final int SORT_DIRECTION_ASC = 2;
    private List<E> paginatedList;
    
    private int pageNumber = 1;
    
    private int pageSize = -99;
    
    private int fullListSize;
    
    private String sortCriterion;
    
    private String Message=null;

	private int sortDirection = 2; //2 : ascending, else: descending 
	

	/** 總計物件 */
	private E totalObject;
    
    /**
     * Returns the current partial list
     * @return the current partial list
     */
    public List<E> getPaginatedList()
    {
        return paginatedList;
    }
    
    /**
     * set the current partial list
     */
    public void setPaginatedList(List<E> paginatedList)
    {
        this.paginatedList = paginatedList;
    }

    /**
     * Returns the page number of the partial list (starts from 1)
     * @return the page number of the partial list
     */
    public int getPageNumber()
    {
        return this.pageNumber;
    }
    
    /**
     * Returns the page number of the partial list (starts from 1)
     */
    public void setPageNumber(int pageNumber)
    {
        this.pageNumber = pageNumber;
        if (1 > this.pageNumber)
            this.pageNumber = 1;
    }

    /**
     * Returns the number of objects per page. Unless this page is the last one the partial list should thus have a size
     * equal to the result of this method
     * @return the number of objects per page
     */
    public int getPageSize()
    {
        if (-99 == this.pageSize){
            Map<String, String> values = CodeTableUtil.getInstance().populateCodes(CodeTableUtil.CODE_KIND_PAGE_RECORD_SIZE);
            if (null == values || 0 == values.size())
                this.pageSize = 20;
            else
            {
                try {
                    this.pageSize = Integer.parseInt(values.keySet().iterator().next());
                }
                catch (Exception e) {
                    this.pageSize = 20; 
                }
            }
        }
        return this.pageSize;
    }

    /**
     * set the number of objects per page. Unless this page is the last one the partial list should thus have a size
     * equal to the result of this method
     */
    public void setPageSize(int pageSize)
    {
        this.pageSize = pageSize;
        if (this.pageSize < 1 && -1 != this.pageSize)
        {
            Map<String, String> values = CodeTableUtil.getInstance().populateCodes(CodeTableUtil.CODE_KIND_PAGE_RECORD_SIZE);
            if (null == values || 0 == values.size())
                this.pageSize = 20;
            else
            {
                try {
                    this.pageSize = Integer.parseInt(values.keySet().iterator().next());
                }
                catch (Exception e) {
                    this.pageSize = 20; 
                }
            } 
        }
    }

    /**
     * Returns the size of the full list
     * @return the size of the full list
     */
    public int getFullListSize()
    {
        return this.fullListSize;
    }

    /**
     * set the size of the full list
     */
    public void setFullListSize(int fullListSize)
    {
        this.fullListSize = fullListSize;
    }

    /**
     * Returns the sort criterion used to externally sort the full list
     * @return the sort criterion used to externally sort the full list
     */
    public String getSortCriterion()
    {
        return this.sortCriterion;
    }

    /**
     * set the sort criterion used to externally sort the full list
     */
    public void setSortCriterion(String sortCriterion)
    {
        this.sortCriterion = sortCriterion;
    }

    public String getMessage() {
		return this.Message;
	}

	public void setMessage(String message) {
		this.Message = message;
	}
    /**
     * Returns the sort direction used to externally sort the full list
     * @return the sort direction used to externally sort the full list, 2 : ascending, else: descending
     */
    public int getSortDirection()
    {
        return this.sortDirection;
    }

    /**
     * set the sort direction used to externally sort the full list, 2 : ascending, else: descending
     */
    public void setSortDirection(int sortDirection)
    {
        this.sortDirection = sortDirection;
    }
    
    /**
     * Returns the computed number of pages it would take to show all the elements in the list given the pageSize we are
     * working with.
     * @return int computed number of pages
     */
    public int getTotalPageCount()
    {
        if (-1 == this.pageSize) //顯示全部，所以只有一頁
            return 1;
        
        int size = this.fullListSize;
        int div = size / this.pageSize;
        int result = (size % this.pageSize == 0) ? div : div + 1;

        return result;
    }
    
    /**
     * Returns the index into the master list of the first object that should appear on the current page that the user
     * is viewing.
     * @return int index of the first object that should appear on the current page
     */
    public int getFirstIndexForCurrentPage()
    {
        return getFirstIndexForPage(this.pageNumber);
    }

    /**
     * Returns the index into the master list of the last object that should appear on the current page that the user is
     * viewing.
     * @return int
     */
    protected int getLastIndexForCurrentPage()
    {

        return getLastIndexForPage(this.pageNumber);
    }

    /**
     * Returns the index into the master list of the first object that should appear on the given page.
     * @param pageNumber page number
     * @return int index of the first object that should appear on the given page
     */
    protected int getFirstIndexForPage(int pageNumber)
    {
        if (-1 == this.pageSize) //顯示全部，所以從第0筆開始顯示
            return 0;
        
        int retval = (pageNumber - 1) * this.pageSize;
        return retval >= 0 ? retval : 0;
    }

    /**
     * Returns the index into the master list of the last object that should appear on the given page.
     * @param pageNumber page number
     * @return int index of the last object that should appear on the given page
     */
    protected int getLastIndexForPage(int pageNumber)
    {

        int firstIndex = getFirstIndexForPage(pageNumber);
        int pageIndex = this.pageSize - 1;
        int lastIndex = this.fullListSize - 1;

        return Math.min(firstIndex + pageIndex, lastIndex);
    }

    /**
	 * 是否最後一頁
	 * 
	 * @return
	 */
	public boolean isLastPage() {
		return getTotalPageCount() <= this.pageNumber;
	}

	public E getTotalObject() {
		return totalObject;
	}

	public void setTotalObject(E totalObject) {
		this.totalObject = totalObject;
	}

    
    
    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("PaginatedList [pageNumber=").append(pageNumber).append(", pageSize=").append(pageSize).append(", fullListSize=").append(fullListSize).append(", sortCriterion=").append(sortCriterion).append(", sortDirection=").append(sortDirection).append("]");
        return builder.toString();
    }

}
